package handler

import (
	"net/http"
	"strconv"

	"fitness/go-admin/internal/model"
	"fitness/go-admin/internal/service"
	"fitness/go-admin/pkg/response"

	"github.com/gin-gonic/gin"
)

// NotificationHandler 通知处理器
type NotificationHandler struct {
	notificationService service.NotificationService
}

// NewNotificationHandler 创建通知处理器实例
func NewNotificationHandler(notificationService service.NotificationService) *NotificationHandler {
	return &NotificationHandler{
		notificationService: notificationService,
	}
}

// ==================== 通知管理 ====================

// GetNotifications 获取通知列表
// @Summary 获取通知列表
// @Description 获取当前用户的站内信通知列表
// @Tags 通知推送
// @Produce json
// @Security ApiKeyAuth
// @Param type query string false "通知类型（COURSE/CARD/SYSTEM/OTHER）"
// @Param is_read query boolean false "是否已读"
// @Param page query int false "页码（默认1）"
// @Param page_size query int false "每页数量（默认20）"
// @Success 200 {object} response.Response{data=model.NotificationListResp}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/notifications [get]
func (h *NotificationHandler) GetNotifications(c *gin.Context) {
	var req model.NotificationListReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数错误: "+err.Error())
		return
	}

	// 从上下文中获取用户ID
	userID := uint(1) // 示例值，实际应从token中获取

	resp, err := h.notificationService.GetUserNotifications(userID, &req)
	if err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, resp, "获取成功")
}

// GetUnreadCount 获取未读数量
// @Summary 获取未读数量
// @Description 获取当前用户未读通知数量
// @Tags 通知推送
// @Produce json
// @Security ApiKeyAuth
// @Success 200 {object} response.Response{data=model.UnreadCountResp}
// @Failure 500 {object} response.Response
// @Router /api/v1/notifications/unread-count [get]
func (h *NotificationHandler) GetUnreadCount(c *gin.Context) {
	// 从上下文中获取用户ID
	userID := uint(1) // 示例值，实际应从token中获取

	resp, err := h.notificationService.GetUnreadCount(userID)
	if err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, resp, "获取成功")
}

// MarkAsRead 标记为已读
// @Summary 标记为已读
// @Description 将指定通知标记为已读
// @Tags 通知推送
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "通知ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/notifications/{id}/read [put]
func (h *NotificationHandler) MarkAsRead(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		response.Error(c, http.StatusBadRequest, "通知ID格式错误")
		return
	}

	// 从上下文中获取用户ID
	userID := uint(1) // 示例值，实际应从token中获取

	if err := h.notificationService.MarkAsRead(uint(id), userID); err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, nil, "已标记为已读")
}

// MarkBatchAsRead 批量标记已读
// @Summary 批量标记已读
// @Description 批量将通知标记为已读
// @Tags 通知推送
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body model.ReadBatchReq true "批量标记请求"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/notifications/read-batch [put]
func (h *NotificationHandler) MarkBatchAsRead(c *gin.Context) {
	var req model.ReadBatchReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数错误: "+err.Error())
		return
	}

	// 从上下文中获取用户ID
	userID := uint(1) // 示例值，实际应从token中获取

	if err := h.notificationService.MarkBatchAsRead(&req, userID); err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, nil, "批量标记成功")
}

// MarkAllAsRead 全部标记已读
// @Summary 全部标记已读
// @Description 将所有通知标记为已读
// @Tags 通知推送
// @Produce json
// @Security ApiKeyAuth
// @Param type query string false "通知类型（不传则全部标记）"
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/notifications/read-all [put]
func (h *NotificationHandler) MarkAllAsRead(c *gin.Context) {
	typ := c.Query("type")

	// 从上下文中获取用户ID
	userID := uint(1) // 示例值，实际应从token中获取

	if err := h.notificationService.MarkAllAsRead(userID, typ); err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, nil, "全部标记成功")
}

// DeleteNotification 删除通知
// @Summary 删除通知
// @Description 删除指定通知
// @Tags 通知推送
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "通知ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/notifications/{id} [delete]
func (h *NotificationHandler) DeleteNotification(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		response.Error(c, http.StatusBadRequest, "通知ID格式错误")
		return
	}

	// 从上下文中获取用户ID
	userID := uint(1) // 示例值，实际应从token中获取

	if err := h.notificationService.DeleteNotification(uint(id), userID); err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, nil, "删除成功")
}

// ==================== 系统公告 ====================

// GetAnnouncements 获取公告列表
// @Summary 获取公告列表
// @Description 获取系统公告列表
// @Tags 通知推送
// @Produce json
// @Security ApiKeyAuth
// @Param type query string false "公告类型（NOTICE/EVENT/MAINTENANCE/PROMOTION）"
// @Param page query int false "页码"
// @Param page_size query int false "每页数量"
// @Success 200 {object} response.Response{data=model.AnnouncementListResp}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/announcements [get]
func (h *NotificationHandler) GetAnnouncements(c *gin.Context) {
	var req model.AnnouncementListReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数错误: "+err.Error())
		return
	}

	resp, err := h.notificationService.GetAnnouncements(&req)
	if err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, resp, "获取成功")
}

// GetAnnouncementDetail 获取公告详情
// @Summary 获取公告详情
// @Description 获取系统公告详情
// @Tags 通知推送
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "公告ID"
// @Success 200 {object} response.Response{data=model.Announcement}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/announcements/{id} [get]
func (h *NotificationHandler) GetAnnouncementDetail(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		response.Error(c, http.StatusBadRequest, "公告ID格式错误")
		return
	}

	// 从上下文中获取用户ID
	userID := uint(1) // 示例值，实际应从token中获取

	announcement, err := h.notificationService.GetAnnouncementDetail(uint(id), userID)
	if err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, announcement, "获取成功")
}

// CreateAnnouncement 创建公告（管理员）
// @Summary 创建公告
// @Description 管理员创建系统公告
// @Tags 通知推送
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body model.CreateAnnouncementReq true "创建公告请求"
// @Success 200 {object} response.Response{data=model.Announcement}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/announcements [post]
func (h *NotificationHandler) CreateAnnouncement(c *gin.Context) {
	var req model.CreateAnnouncementReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数错误: "+err.Error())
		return
	}

	// 从上下文中获取创建者ID
	creatorID := uint(1) // 示例值，实际应从token中获取

	announcement, err := h.notificationService.CreateAnnouncement(&req, creatorID)
	if err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, announcement, "创建成功")
}

// UpdateAnnouncement 更新公告（管理员）
// @Summary 更新公告
// @Description 管理员更新系统公告
// @Tags 通知推送
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "公告ID"
// @Param request body model.UpdateAnnouncementReq true "更新公告请求"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/announcements/{id} [put]
func (h *NotificationHandler) UpdateAnnouncement(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		response.Error(c, http.StatusBadRequest, "公告ID格式错误")
		return
	}

	var req model.UpdateAnnouncementReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数错误: "+err.Error())
		return
	}

	// 从上下文中获取创建者ID
	creatorID := uint(1) // 示例值，实际应从token中获取

	if err := h.notificationService.UpdateAnnouncement(uint(id), &req, creatorID); err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, nil, "更新成功")
}

// DeleteAnnouncement 删除公告（管理员）
// @Summary 删除公告
// @Description 管理员删除系统公告
// @Tags 通知推送
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "公告ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/announcements/{id} [delete]
func (h *NotificationHandler) DeleteAnnouncement(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		response.Error(c, http.StatusBadRequest, "公告ID格式错误")
		return
	}

	// 从上下文中获取创建者ID
	creatorID := uint(1) // 示例值，实际应从token中获取

	if err := h.notificationService.DeleteAnnouncement(uint(id), creatorID); err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, nil, "删除成功")
}

// PublishAnnouncement 发布公告（管理员）
// @Summary 发布公告
// @Description 管理员发布公告
// @Tags 通知推送
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "公告ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/announcements/{id}/publish [post]
func (h *NotificationHandler) PublishAnnouncement(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		response.Error(c, http.StatusBadRequest, "公告ID格式错误")
		return
	}

	// 从上下文中获取创建者ID
	creatorID := uint(1) // 示例值，实际应从token中获取

	if err := h.notificationService.PublishAnnouncement(uint(id), creatorID); err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, nil, "发布成功")
}

// ==================== 通知模板管理（管理员） ====================

// GetTemplates 获取模板列表（管理员）
// @Summary 获取模板列表
// @Description 管理员获取通知模板列表
// @Tags 通知推送
// @Produce json
// @Security ApiKeyAuth
// @Param page query int false "页码"
// @Param page_size query int false "每页数量"
// @Success 200 {object} response.Response{data=model.TemplateListResp}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/notifications/templates [get]
func (h *NotificationHandler) GetTemplates(c *gin.Context) {
	var req model.TemplateListReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数错误: "+err.Error())
		return
	}

	resp, err := h.notificationService.GetTemplates(&req)
	if err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, resp, "获取成功")
}

// CreateTemplate 创建模板（管理员）
// @Summary 创建模板
// @Description 管理员创建通知模板
// @Tags 通知推送
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body model.CreateTemplateReq true "创建模板请求"
// @Success 200 {object} response.Response{data=model.Template}
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/notifications/templates [post]
func (h *NotificationHandler) CreateTemplate(c *gin.Context) {
	var req model.CreateTemplateReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数错误: "+err.Error())
		return
	}

	template, err := h.notificationService.CreateTemplate(&req)
	if err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, template, "创建成功")
}

// UpdateTemplate 更新模板（管理员）
// @Summary 更新模板
// @Description 管理员更新通知模板
// @Tags 通知推送
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "模板ID"
// @Param request body model.UpdateTemplateReq true "更新模板请求"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/notifications/templates/{id} [put]
func (h *NotificationHandler) UpdateTemplate(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		response.Error(c, http.StatusBadRequest, "模板ID格式错误")
		return
	}

	var req model.UpdateTemplateReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数错误: "+err.Error())
		return
	}

	if err := h.notificationService.UpdateTemplate(uint(id), &req); err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, nil, "更新成功")
}

// DeleteTemplate 删除模板（管理员）
// @Summary 删除模板
// @Description 管理员删除通知模板
// @Tags 通知推送
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "模板ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/notifications/templates/{id} [delete]
func (h *NotificationHandler) DeleteTemplate(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		response.Error(c, http.StatusBadRequest, "模板ID格式错误")
		return
	}

	if err := h.notificationService.DeleteTemplate(uint(id)); err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, nil, "删除成功")
}

// ==================== 通知设置 ====================

// GetNotificationSettings 获取通知设置
// @Summary 获取通知设置
// @Description 获取当前用户的通知设置
// @Tags 通知推送
// @Produce json
// @Security ApiKeyAuth
// @Success 200 {object} response.Response{data=model.NotificationSettingsResp}
// @Failure 500 {object} response.Response
// @Router /api/v1/notifications/settings [get]
func (h *NotificationHandler) GetNotificationSettings(c *gin.Context) {
	// 从上下文中获取用户ID
	userID := uint(1) // 示例值，实际应从token中获取

	resp, err := h.notificationService.GetUserSettings(userID)
	if err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, resp, "获取成功")
}

// UpdateNotificationSettings 更新通知设置
// @Summary 更新通知设置
// @Description 更新当前用户的通知设置
// @Tags 通知推送
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body model.UpdateSettingsReq true "更新设置请求"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/notifications/settings [put]
func (h *NotificationHandler) UpdateNotificationSettings(c *gin.Context) {
	var req model.UpdateSettingsReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数错误: "+err.Error())
		return
	}

	// 从上下文中获取用户ID
	userID := uint(1) // 示例值，实际应从token中获取

	if err := h.notificationService.UpdateUserSettings(&req, userID); err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, nil, "更新成功")
}

// ==================== 系统推送（内部接口） ====================

// SendCourseReminder 发送课程提醒
// @Summary 发送课程提醒
// @Description 内部接口：发送课程提醒通知
// @Tags 通知推送
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body model.SendCourseReminderReq true "发送课程提醒请求"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/notifications/send/course-reminder [post]
func (h *NotificationHandler) SendCourseReminder(c *gin.Context) {
	var req model.SendCourseReminderReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数错误: "+err.Error())
		return
	}

	if err := h.notificationService.SendCourseReminder(&req); err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, nil, "发送成功")
}

// SendCardExpireReminder 发送会员卡到期提醒
// @Summary 发送会员卡到期提醒
// @Description 内部接口：发送会员卡到期提醒通知
// @Tags 通知推送
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body model.SendCardExpireReq true "发送会员卡到期提醒请求"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/notifications/send/card-expire [post]
func (h *NotificationHandler) SendCardExpireReminder(c *gin.Context) {
	var req model.SendCardExpireReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数错误: "+err.Error())
		return
	}

	if err := h.notificationService.SendCardExpireReminder(&req); err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, nil, "发送成功")
}

// SendAnnouncement 批量推送公告
// @Summary 批量推送公告
// @Description 内部接口：批量推送公告通知
// @Tags 通知推送
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body model.SendAnnouncementReq true "批量推送公告请求"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/notifications/send/announcement [post]
func (h *NotificationHandler) SendAnnouncement(c *gin.Context) {
	var req model.SendAnnouncementReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数错误: "+err.Error())
		return
	}

	if err := h.notificationService.SendAnnouncement(&req); err != nil {
		response.Error(c, http.StatusInternalServerError, err.Error())
		return
	}

	response.Success(c, nil, "发送成功")
}